package org.datascooter.tansaction;

import java.util.ArrayList;
import java.util.List;

import org.datascooter.exception.DataScooterException;

/**
 * Purpose for an execution of transactions even distributed
 * 
 * @author nemo
 * 
 */
public class Transaction extends Thread {

	private List<Task> taskList = new ArrayList<Task>();
	private boolean interrupt = false;
	private final String transactionId;

	public Transaction(String transactionId) {
		this.transactionId = transactionId;
	}

	public void addTask(Task task) {
		taskList.add(task);
	}

	private void begin() {
		for (Task task : taskList) {
			if (!interrupt) {
				task.beginTransaction(transactionId);
			}
		}
	}

	private void runTransaction() {
		for (Task task : taskList) {
			if (!interrupt) {
				task.run();
			}
		}
	}

	private void commit() {
		for (Task task : taskList) {
			task.commit();
		}
	}

	private void rollback() {
		for (Task task : taskList) {
			try {
				task.rollback();
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void run() {
		runSync();
	}

	private void requestCommit() {
		for (Task task : taskList) {
			task.requestCommit();
		}
	}

	public void runSync() {
		begin();
		try {
			runTransaction();
			requestCommit();
			if (interrupt) {
				rollback();
			} else {
				commit();
			}
		} catch (Exception e) {
			rollback();
			throw new DataScooterException(e);
		}
	}

	public void setInterrupt(boolean interrupt) {
		this.interrupt = interrupt;
	}

	public String getTransactionId() {
		return transactionId;
	}
}
